package com.xuan.task.controller;

import com.xuan.task.Mapper.*;
import com.xuan.task.domain.*;
import com.xuan.task.service.LogService;
import com.xuan.task.service.UserStatisticService;
import com.xuan.task.utils.WordFileTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * FileName: QuartzComponent
 * Author:   xuan zongjun
 * Date:     2020/8/24 13:50
 * Description:
 */

@Component
public class QuartzComponent {
    @Autowired
    LogService logService;

    @Autowired
    ExamHomeworkMapper examHomeworkMapper;
    @Autowired
    WordPracticeFileMapper wordPracticeFileMapper;
    @Autowired
    private UserStatisticService userStatisticService;
    @Autowired
    private ElectronicBookPracticeResultMapper electronicBookPracticeResultMapper;
    @Autowired
    private WordPracticeRecordsMapper wordPracticeRecordsMapper;
    @Autowired
    private ElectronicBookMapper electronicBookMapper;
    @Autowired
    private WordPracticeHistoryMapper wordPracticeHistoryMapper;




    /**
     * 学情分析总结报告：生成作业 和 练习当天的数据
     */
    public void createNotDoneHomeworkAndPractice() {
        try {
            //首先获取作业列表
            String now = LocalDate.now().toString();
            List<HomeworkView> homeworkViewList = examHomeworkMapper.getHomeworkListAllByLastestTime( now );
            for (HomeworkView homeworkView : homeworkViewList) {
                userStatisticService.insertUserHomeworkExampaperHistory( homeworkView );
            }
        } catch (Exception ex) {
            logService.insertLog( new Logs( "createHomeworkOrPracticeRecord", "生成练习记录和作业记录", ex.getMessage(), new Date() ) );
        }

    }
    private final  static  Integer num =4;
    //多线程
    private final static Executor executor = Executors.newFixedThreadPool( num );


    /**
     * 计算用户 每个电子书完成的百分比 和 练习的单词个数
     */
    public void createUserPracticeResultByBookNum() {
        //删除所有记录
        //electronicBookPracticeResultMapper.deleteAll();
        //首先获取所有的用户ID，从表：word_practice_file 和  word_practice_records
        //从昨天 23 点 到 今天晚上24点查询用户
        LocalDate now = LocalDate.now();
        LocalDate yesterday = now.minusDays( 1 );
        String endTime = now + " 23:59:59";
        String startTime = yesterday + " 23:00:00";
        List<String> allUser = wordPracticeRecordsMapper.getAllUserIdFromWordFileAndWordRecords( startTime, endTime );
        logService.insertLog( new Logs("taskJob-createUserPracticeResultByBookNum", "定时任务-电子书完成情况统计-task","总的用户数："+allUser.size(),new Date(  )  ) );


        //获取电子书列表
        List<String> bookList = electronicBookMapper.getElectronicBookByType( 1 );
        //每个电子书中
        List<EBookAndCount> eBookAndCounts = electronicBookMapper.getEBookWordCountByBookNum( bookList );

        //不用多线程处理
        //getElectronicBookNum(eBookAndCounts,allUser,0,allUser.size());

        //使用多线程处理
        int length = allUser.size();
        int baseNum = length / num;
        int remainderNum = length % num;
        int end  = 0;
        for (int i = 0; i < num; i++) {
            int start = end;
            end = start + baseNum;
            if (i == (num - 1)) {
                end = length;
            } else if (i < remainderNum) {
                end = end + 1;
            }
            //使用多线程处理
            int finalEnd = end;
            executor.execute( new Runnable() {
                @Override
                public void run() {
                    getElectronicBookNum( eBookAndCounts, allUser,start, finalEnd );
                    logService.insertLog( new Logs("taskJob-createUserPracticeResultByBookNum", "线程池执行情况","处理第"+start+"个到第"+finalEnd+"个用户的数据",new Date(  )  ) );
                }
            } );
        }

    }

    private  void getElectronicBookNum(List<EBookAndCount> eBookAndCounts, List<String> allUser,int start,int end) {
        List<String> stringList = allUser.subList( start, end );
        for (String userId : stringList) {
            for (EBookAndCount eBookAndCount : eBookAndCounts) {
                String bookNum = eBookAndCount.getBook_num();
                //电子书中单词的数量
                int vocabularyCount = eBookAndCount.getNum();
                //获取用户每个电子书中练习的单词列表
                List<String> wordList = wordPracticeRecordsMapper.getUserWordListByBookNumAndUserId( userId, bookNum );
                if (wordList.size() > 0) {
                    //判断是否存在
                    ElectronicBookPracticeResult byUserIdAndBookNum = electronicBookPracticeResultMapper.getByUserIdAndBookNum( userId, bookNum );
                    ElectronicBookPracticeResult result = new ElectronicBookPracticeResult();
                    result.setBook_num( bookNum );
                    result.setUser_id( userId );
                    double percentComplete = this.getPercentComplete( userId, wordList );
                    result.setPercent_complete( percentComplete );
                    result.setPractice_word_count( wordList.size() );
                    //计算拼写进度、背诵进度、朗读发音进度、选择进度
                    Map<String, Double> wordPercentComplete = this.getWordPercentComplete( userId, bookNum, vocabularyCount );
                    result.setWrite_percent_complete( wordPercentComplete.get( "writePercentComplete" ) );
                    result.setRecite_percent_complete( wordPercentComplete.get( "recitePercentComplete" ) );
                    result.setRead_percent_complete( wordPercentComplete.get( "readPercentComplete" ) );
                    result.setChose_percent_complete( wordPercentComplete.get( "chosePercentComplete" ) );

                    if (byUserIdAndBookNum == null) {
                        electronicBookPracticeResultMapper.insert( result );
                    } else {
                        electronicBookPracticeResultMapper.update( result );
                    }
                }
            }
        }
    }

    /**
     * 返回单词的完成度
     *
     * @param userId          用户ID
     * @param bookNum         电子书编号
     * @param vocabularyCount 单词资源包单词数量
     * @return
     */
    private Map<String, Double> getWordPercentComplete(String userId, String bookNum, int vocabularyCount) {
        Map<String, Double> resultMap = new HashMap<>();

        //定义拼写、背诵、发音的完成度
        double writePercentComplete = 0;
        double recitePercentComplete = 0;
        double readPercentComplete = 0;
        double chosePercentComplete = 0;

        //单词发音，分数要大于80分的才算合格
        List<WordAndCount> wordAndCountList = wordPracticeRecordsMapper.getWordAndCountByBookNumAndUserId( userId, bookNum );
        readPercentComplete = wordAndCountList.size() * 1.0 / vocabularyCount;

        resultMap.put( "readPercentComplete", getTwoDecimalDouble( readPercentComplete ) );
        //拼写 和  背诵 要正确才算合格
        //包含拼写和背诵
        List<WordAndCount> wordTypeAndCountList = wordPracticeHistoryMapper.getWordAndCountByUserIdAndBookNum( userId, bookNum );
        //拼写
        List<WordAndCount> writeCountList = wordTypeAndCountList.stream().filter( word -> word.getType() == 2 ).collect( Collectors.toList() );
        //背诵
        List<WordAndCount> reciteCountList = wordTypeAndCountList.stream().filter( word -> word.getType() == 3 ).collect( Collectors.toList() );
        //选择
        List<WordAndCount> choseCountList = wordTypeAndCountList.stream().filter( word -> word.getType() == 5 ).collect( Collectors.toList() );

        //拼写
        //单词发音，分数要大于80分的才算合格
        writePercentComplete = writeCountList.size() * 1.0 / vocabularyCount;
        resultMap.put( "writePercentComplete", getTwoDecimalDouble( writePercentComplete ) );

        //背诵
        recitePercentComplete = reciteCountList.size() * 1.0 / vocabularyCount;
        resultMap.put( "recitePercentComplete", getTwoDecimalDouble( recitePercentComplete ) );

        //选择
        chosePercentComplete = choseCountList.size() * 1.0 / vocabularyCount;
        resultMap.put( "chosePercentComplete", getTwoDecimalDouble( chosePercentComplete ) );


        return resultMap;
    }

    /**
     * 获取完成的百分比
     *
     * @param userId
     * @param wordList
     * @return
     */
    private Double getPercentComplete(String userId, List<String> wordList) {
        //计算掌握程度,通过单词列表和userId获取单词档案记录
        List<WordPracticeFile> wordPracticeFileList = wordPracticeFileMapper.getListByUserIdAndWordList( userId, wordList );
        if (wordPracticeFileList != null && wordPracticeFileList.size() > 0) {
            //对单词档案列表，判断牢固和熟练的单词
            WordFileTypeUtils.setWordFileType( wordPracticeFileList );
            //牢固和熟练的总数 / 资源包单词个数 = 掌握程度
            long count = wordPracticeFileList.stream().filter( file -> file.getType() == 1 || file.getType() == 2 ).count();
            double percentComplete = count * 1.0 / wordList.size();
            return getTwoDecimalDouble( percentComplete );
        } else {
            return 0D;
        }
    }

    //返回两位小数的数据
    private double getTwoDecimalDouble(double oldNumber) {
        BigDecimal bg = new BigDecimal( oldNumber );
        oldNumber = bg.setScale( 2, BigDecimal.ROUND_HALF_UP ).doubleValue();
        return oldNumber > 1 ? 1 : oldNumber;//百分最大为百分百
    }




}
